/*
@filename		:  base.js
@description	: basic core of library
-----------------------------------------------------------------------------
@author	:  ScriptPower     <a href="mailto:scriptpower@qq.com">scriptpower@qq.com</a>
@update	:  2010-12-30
*/

(function(W){
    // TODO: 库的名称待定
    var _SP = W.SP,
		S,
		_ = {},
		trim	 = String.prototype.trim,
		//trim	Left = String.prototype.trim	Left,
		//trim	Right = String.prototype.trimRight,
		slice	 = Array.prototype.slice,
        toString = Object.prototype.toString,
		hasOwnProperty = Object.prototype.hasOwnProperty,
		rDashAlpha = /-([a-z])/ig,
		fCamelCase = function ( all, letter ) {
			return letter.toUpperCase();
		},
		eachArray,
		spFunc,
		SF = {},
		types = {};

    /**
     * 库的顶层命名空间, 使用者通过该对象调用库中的方法及类型.
     * @namespace SP
     * @global
     */
    W.SP = S = function (o, thisp){
			alert("待定");
			return ;
			var  t=  toString.call(o).slice(8,-1);
			if(SF.hasOwnProperty(t))return SF[t](o);
			return S;
	};

	S._	 = _;	 //占位符

	//对象成员定义
	S.define	 = function (/*dest [, overwrite], keyA, valueA, keyB, valueB ... keyZ, valueZ*/){
		var args =arguments , l =args.length -1, i, dest, x;
		if( l >= 2 && (dest = args[0])){
			//type = typeof(dest);
			//if( (type == "object" && args[0]) || type== "function"){
				if(args[1] === true){// 覆盖模式
					for(i=2; i<l ;i+=2) dest[args[i]] = args[i+1];
				} else {//追加模式
					for(i=1; i<l ;i+=2) {
						x = args[i];
						if(!dest.hasOwnProperty(x))  dest[ x ] = args[i+1];
					}
				}
			//}
		}
		return this;
	};

    /**
     * 扩充对象成员, 将来源对象 (src) 中的成员复制到目标对象 (dest) 中.
     * @method extend
     * @param {Object|Function} dest 目标对象
     * @param {Boolean} overwrite 如果有同名属性是否覆盖, 默认为 false
     * @param {Object|Function} src 来源对象
     * @return this
     */
    S.extend = function (/*dest [, overwrite] , srcA , srcB, ...  srcZ*/) {
		var args = arguments, l = args.length, i , dest , src, x;
		//if(l > 1 && (dest = args[0]) && (typeof(dest) == "object" || typeof(dest) =="function")){
		if(l > 1 && (dest = args[0])){
			if(true == args[1]){//覆盖模式
				for(i=2; i<l;i++) {
					src = args[i];
					if(src && dest!== src){
						for(x in src)  dest[x] = src[x];
					}
				}
			} else {//新建模式
				for(i=1; i<l;i++) {
					src = args[i];
					if(src && dest!== src){
						for(x in src) {
							if (!dest.hasOwnProperty(x)) dest[x] = src[x];
						}
					}
				}
			}
		}
        return this;
    };

	//curry
	function spCurry(fn){
		var args = slice.call(arguments,1);
		return args.length ? function( ) {
			return fn.apply( this, args.concat( slice.call(arguments) ) );
		} : fn;
	}

	//partial
	function spPartial( fn ) {
		var Args = slice.call(arguments,1), l=Args.length;
		return l ? function(){
		  var i=0,j=0,args=[];
		  for (; i < l; i++ ) args[i] = _ === Args[i] ? arguments[j++] : Args[i];
		  return fn.apply(this, args.concat(slice.call(arguments,j)));
		} : fn;
	}

	var bind = Function.prototype.bind,
		spBind;
	if ( bind ) {
		spBind	= function (fn, thisp/* [, arg1 [, arg2 [...] ] ]*/){
			return bind.apply(fn, [ thisp || S].concat(slice.call(arguments, 2)));
			//return bind.apply(fn, slice.call(arguments, 1));
		};
	} else {
		spBind= function ( fn, thisp/* [, arg1 [, arg2 [...] ] ]*/ ) {
			thisp	= thisp || S;
			var args = slice.call(arguments, 2),
				nop = function () {},
				bound = function () {
				  return fn.apply( this instanceof nop ? this : thisp,
									  args.concat( slice.call(arguments) ) );
				};

			nop.prototype = fn.prototype;

			bound.prototype = new nop();

			return bound;
		};
	}
	//alert(spBind);

	//
	function create(attributes){
		var len = attributes.length;
		return function ( fn ){
			var i=0, l = len, x, ret, func = arguments.callee;
			if(arguments.length < 1) return func;
			//ret = function (fn){ return func(fn);	};
			ret = { };
			for(i=0; i<l;i++) {
				x = attributes[i];
				ret[x] = spCurry(func[x], fn);
			}
			return ret;
		};
	}

	//hasKey
	function hasKey(o, k) {
		return o && o.hasOwnProperty && o.hasOwnProperty(k);
		//return hasOwnProperty.call(o, k);
	}

	//map
	function mapObject(obj, change, strict){
		var ret = {}, len = arguments.length, type = typeof(change), x;
		if(len == 1){//原样镜像
			for(x in obj) ret[x] = obj[x];
		} else if(len >1){
			if(change && "object" == type){//替换值
				if(true === strict){//严格模式
					for(x in obj)  ret[x] = change.hasOwnProperty(x) && (typeof(change[x]) == typeof(obj[x]))? change[x] : obj[x];
				} else {
					for(x in obj)  ret[x] = change.hasOwnProperty(x) ? change[x] : obj[x];
				}
			} else if("function" == type){//函数转换
				strict = strict && typeof(strict) == "object" ? strict : S;
				for(x in obj) ret[x] = change.call(strict, obj[x], x , obj);
			}
		}
		return ret;
	}

	//eachArray
	eachArray	= Array.forEach || function (array, callback , thisp) {
		var i = 0, l = array.length;
		for(; i<l ; i++) callback.call(thisp , array[i] , i, array);
	};

	//eachObject
	function eachObject(obj, callback /*, thisp*/){
		var thisp = thisp || S;
		for(x in obj) callback.call(thisp, obj[x], x, obj);
		return this;
	}

	eachArray(["Boolean","Number","String","Function","Array","Date","RegExp","Object"],function (type){
		this[ "[object " + type + "]" ] = type.toLowerCase();
	}, types);

	//type
	function type(o){
		return o === null ? String( o ) : types[ toString.call(o) ] || typeof(o);	//unknow, date
		//return o === null ? String( o ) : types[ toString.call(o) ] || "object";
	}
	

	// core	 : lang - type
	S.define(S,
			"type", type,
			"isArray", Array.isArray || function(o) { // Array.isArray 为 JS 1.8.5 API
				return toString.apply(o)==='[object Array]';
			},

			"isFunction",  function(o) {
				//return type(o) === "function";
				return typeof(o) == "function" || toString.call(o) == "[object Function]";
			},

			"isObject", function (o){
				//return !!o && (o = typeof(o))  && (o== "object" || o=="function");	//包括function
				return !!o && typeof(o) == "object";
			},

			"isPlainObject", function (o){
				// Must be an Object.
				// Because of IE, we also have to check the presence of the constructor property.
				// Make sure that DOM nodes and window oects don't pass through, as well
				if ( !o || toString.call(o) !== "[oect Object]" || o.nodeType || (o.setInterval && o.document) )  return false;

				// Not own constructor property must be Object
				if ( o.constructor
					&& !hasOwnProperty.call(o, "constructor")
					&& !hasOwnProperty.call(o.constructor.prototype, "isPrototypeOf") ) {
					return false;
				}

				// Own properties are enumerated firstly, so to speed up,
				// if last one is own, then all properties are own.

				var key;
				for ( key in o ) {}

				return key === undefined || hasOwnProperty.call( o, key );
			},

			 "isEmptyObject", function(o) {
				if (!S.isObject(o)) return false;
				for (var key in o)  return false;
				return true;
			},

			"isBoolean", function(o) {
				return typeof o === "boolean";
			},

			"isDate", function(o) {
				return type(o) === "date" && o.toString() !== 'Invalid Date' && !isNaN(o);
			},

			"isNull", function(o) {
				return o === null;
			},

			"isNumber", function(o) {
				return typeof o === "number" && isFinite(o);
			},

			"isUndefined", function(o) {
				return typeof o === "undefined";
			},

			"isElement", function(o) {
				return !!(o && (o = o.nodeType) && o === 1);
			},

			"isDocument", function(o) {
				return !!(o && (o = o.nodeType) && o === 9);
			},

			"isWindow", function(o) {
				return !!(o && o.alert && o.document);
			}
	);

	// core	 : lang - method
	S.define(S,
			"trim", trim ?
				function( s ) {
					return s == null ?	"" : trim.call( s );
				} :
				// Otherwise use our own trimming functionality
				function( s ) {
					var s=s.replace(/^\s\s*/,""),
					ws= /\s/,
					i = s.length;
					while(ws.test(s.charAt(--i)));
					return s.slice(0, i + 1);
					//return s == null ? "" : s.toString().replace( trimLeft, "" ).replace( trimRight, "" );
				},
			"camelCase", function (s){//转化为驼峰写法
				return s.replace(rDashAlpha, fCamelCase );
			},
			"now", Date.now || function () {return (new Date()).getTime();}
	);

	//core	: base - modle
	S.define(S,
			"Function", create(["curry","partial","bind"]),
			"Array", create(["forEach", "map", "indexOf", "lastIndexOf", "filter", "every", "some", "remove"]),
			"Object", create(["has", "map", "forEach"]) ,
			"Date", create(["toJSON"]) ,
			"String", create(["trim"])	 /**/
		).define(S.String,
			"trim", S.trim,
			"camelCase", S.camelCase,
			"cint", function(str,radix){//字符串转化为整数
				radix=radix || 10;
				radix= parseInt(""+str,radix);
				return (isNaN(radix)?0:radix);
			},
			"cfloat", function(str){//字符串转化为浮点数
				str= parseFloat(""+str);
				return (isNaN(str)?0:str);
			}
		).define(S.Function,
			"curry", spCurry,
			"partial", spPartial,
			"bind", spBind
		).define(S.Array,
			"forEach", function (array, callback /*, thisp*/){ eachArray(array, callback ,arguments[2] || S);	return this;}
		).define(S.Object,
			"hasKey", hasKey,
			"map", mapObject,
			"forEach", eachObject
		).define(SF,
			"Function", S.Function,
			"Array", S.Array
		);

})(window);